'''
Created on Mar 23, 2013

@author: larsonmp
'''

from argparse import ArgumentParser
import cPickle as pickle
import os
import sys

from data_types.InternetUsageSurvey import CurrentPopulationSurveyInternetRecord, Household, Person, DataError

import grapher
import printer

class Session(object):
    def __init__(self, verbose=False):
        self._households = {}
        self._num_processed = 0
        self._num_accepted = 0
        self._num_rejected = 0
        self._verbose = verbose

    def process(self, record):
        self._num_processed += 1
        try:
            p = Person(record)
            h = self._households.get(p.household_id, None)
            if h is None:
                h = Household(record)
                self._households[p.household_id] = h
            h.append(p)
        except DataError as error:
            self._num_rejected += 1
            if self._verbose:
                sys.stderr.write('skipping record: %s\n' % str(error))
        else:
            self._num_accepted += 1
        assert self.processed == (self.accepted + self.rejected)
    
    def remove(self, household_id):
        household = self._households.pop(household_id, None)
        if household:
            self._num_accepted -= 1
            self._num_rejected += 1
        return household
    
    @property
    def households(self):
        return self._households
    
    @property
    def rejected(self):
        return self._num_rejected
    
    @property
    def accepted(self):
        return self._num_accepted
    
    @property
    def processed(self):
        return self._num_processed

def sanity_check(session, halt_on_error=True, verbose=False):
    num_pruned = 0
    for household in session.households.values():
        try:
            if household.size != len(household):
                raise Exception('[%20d] size mismatch: expected %d, found %d' % (household.id, household.size, len(household)))
            if household.home_internet_access != household.home_internet_access_2:
                raise Exception('[%20d] inconsistent data: %s vs. %s' % (household.id, household.home_internet_access, household.home_internet_access_2))
        except Exception as error:
            if halt_on_error:
                raise
            else:
                if session.remove(household.id):
                    num_pruned += 1
                printer.print_sanity_error(error, household, verbose)
    printer.print_sanity_summary(num_pruned)

if __name__ == '__main__':
    parser = ArgumentParser(description='Parse, process, and print survey data')
    parser.add_argument('-f', '--file',    dest='input_file_path', default='../data/jul11pub.dat', metavar='PATH', help='input file [default: %(default)s]')
    parser.add_argument('--no-cache', dest='cache', action='store_false', help='caching [default: %(default)s]')
    parser.add_argument('-v', '--verbose', dest='verbose', action='count', help='verboseness level [default: %(default)s]')
    
    args = parser.parse_args()
    
    session = None
    cache_filepath = args.input_file_path + '.cache'
    
    if args.cache and os.path.exists(cache_filepath):
        with open(cache_filepath, 'rb') as cache_file:
            session = pickle.load(cache_file)
    else:
        session = Session(args.verbose)
        with open(args.input_file_path) as input_file:
            for line in input_file:
                record = CurrentPopulationSurveyInternetRecord(line)
                session.process(record)
        sanity_check(session, False, args.verbose)

#    printer.print_associations(session)
#    printer.print_statistics(session)
    grapher.graph_session(session, args.verbose)
#    print_session(session, hids=[94096109334319989001, 85060487079650887001])
    
    #refresh cache
    if args.cache and not os.path.exists(cache_filepath):
        sys.stdout.write('creating cache... ')
        with open(cache_filepath, 'wb') as cache_file:
            pickle.dump(session, cache_file)
        print 'done'
